package br.com.basili.mb;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.ViewScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.model.ListDataModel;
import javax.servlet.http.HttpServletRequest;

import com.lowagie.text.pdf.PRTokeniser;

import br.com.basili.dao.ProtocoloDAO;
import br.com.basili.dao.QuestionDAO;
import br.com.basili.dao.ResearcherDAO;
import br.com.basili.entity.AlternativeHypotheses;
import br.com.basili.entity.Characterization;
import br.com.basili.entity.Context;
import br.com.basili.entity.CostPlanning;
import br.com.basili.entity.Definition;
import br.com.basili.entity.Generality;
import br.com.basili.entity.Identification;
import br.com.basili.entity.Introduction;
import br.com.basili.entity.Metric;
import br.com.basili.entity.Planning;
import br.com.basili.entity.Process;
import br.com.basili.entity.Protocol;
import br.com.basili.entity.Question;
import br.com.basili.entity.Reality;
import br.com.basili.entity.RelacaoMetricaQuestionID;
import br.com.basili.entity.RelacaoProtocoloFases;
import br.com.basili.entity.RelacaoProtocoloMetricaID;
import br.com.basili.entity.Researcher;
import br.com.basili.entity.Study;
import br.com.basili.entity.Troop;
import br.com.basili.entity.Type;
import br.com.basili.entity.Variable;
import br.com.basili.utility.UrlsBASILI;

@ManagedBean
@ViewScoped
public class ProtocolMB extends GenericBean {
	
	private final static String cadastrar = "cadastrar";
	private final static String editar    = "editar";
	
	private String acao;
	
	
	//Protocolo
	private Protocol         protocol;
	
	//Fases do Estudo
	private Identification   identification;
	private Introduction     introduction;
	private Characterization characterization;
	private Definition       definition;
	private Planning         planning;
	private CostPlanning     costPlanning;
	
	private Metric           selectedMetric;
	private String           title;
	private String           theme;
	private Researcher       researcher;
	private List<Researcher> listResearcher;
	private List<Researcher> listResearcher2;
	private Study[]          listaTiposEstudo;
	private Context[]        listaContexto;
    private List<Metric>     listaMetricas;
	private Process[]        process;
	private Reality[]        reality;
	private Generality[]     generality;
	private Metric           metric;
	private Question         question;
	private Troop            group;
	private List<Variable>   listVariable;
	private Variable         variable;
	private List<RelacaoProtocoloFases> listRPF;
	private AlternativeHypotheses alternativeHypotheses;
	private List<Question>   listaQuestions; 
	private ResearcherDAO researcherDAO = new ResearcherDAO();
	private List<Protocol> listProtocol;
	private List<AlternativeHypotheses> lAlternativeHypotheses = new ArrayList<AlternativeHypotheses>();
	private List<Troop> listGroups = new ArrayList<Troop>();
	ProtocoloDAO dao = new ProtocoloDAO();
	
	private static int contador = 0;
	
	public ProtocolMB() {
		
		if( getAcao().equals(editar) )
		{
			FacesContext fc = FacesContext.getCurrentInstance();
			Map<String,String> params = fc.getExternalContext().getRequestParameterMap();
			int cod = Integer.parseInt(params.get("codigo"));
			try {
				protocol = dao.getProtocolPorCodigo(cod);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			setIdentification(protocol.getIdentification());
			setIntroduction(protocol.getIntroduction());
			setCharacterization(protocol.getCharacterization());
			setDefinition(protocol.getDefinition());
			setPlanning(protocol.getPlanning());
			setListResearcher2(identification.getResearchers());
			setListaMetricas(getDefinition().getListMetric());
			setlAlternativeHypotheses(getPlanning().getAlternativeHypotheses());
			setListGroups(getPlanning().getGroups());                           
			setListVariable(getPlanning().getVariables()); 
		}else{
		
		identification   = new Identification();
		introduction     = new Introduction();
		characterization = new Characterization();
		definition       = new Definition();
		planning         = new Planning();
		costPlanning     = new CostPlanning();
		researcher       = new Researcher();
		listResearcher2  = new ArrayList<Researcher>();
		metric           = new Metric();
		question         = new Question();
		group            = new Troop();
		protocol         = new Protocol();
		variable         = new Variable();
		listVariable     = new ArrayList<Variable>();
		selectedMetric   = new Metric();
		listProtocol     = new ArrayList<Protocol>();
		listaMetricas    = new ArrayList<Metric>();
		listaQuestions    = new ArrayList<Question>();
		listRPF = new ArrayList<RelacaoProtocoloFases>();
		alternativeHypotheses = new AlternativeHypotheses();
		 lAlternativeHypotheses = new ArrayList<AlternativeHypotheses>();
		 listGroups = new ArrayList<Troop>();
		setListResearcher(researcherDAO.getListResearcher());
		}
		
	}
	
	public String getAcao(){
		FacesContext fc = FacesContext.getCurrentInstance();
		Map<String,String> params = fc.getExternalContext().getRequestParameterMap();
		String acao = params.get("acao");
		if( acao != null ) 
			return acao;
		return "";
	}
	
	public void save() {  
        try
        {
        	for( int i = 0; i < listaMetricas.size(); i++ )
        	{
        		Metric m = listaMetricas.get(i);
        		for( Question q : listaQuestions )
        			if( q.getMetric().equals(m))
        				m.getQuestions().add(q);
        		m.getId().setDefinition(definition);
        		listaMetricas.set(i,m);
        	}
        	identification.setResearchers(getListResearcher2());
        	definition.setListMetric(listaMetricas);
        	planning.setAlternativeHypotheses(getlAlternativeHypotheses());
        	planning.setGroups(getListGroups());
        	planning.setVariables(getListVariable());
        	protocol.setCharacterization(characterization);
        	protocol.setDefinition(definition);
        	protocol.setIdentification(identification);
        	protocol.setIntroduction(introduction);
        	protocol.setPlanning(planning);
			dao.salvar(protocol);
			
			FacesMessage msg = new FacesMessage("Salvo" );  
	        FacesContext.getCurrentInstance().addMessage(null, msg); 
			
			protocol = new Protocol();
			characterization = new Characterization();
			definition = new Definition();
			identification = new Identification();
			introduction = new Introduction();
			planning = new Planning();
		} catch (Exception e) {
			FacesMessage msg = new FacesMessage("Erro ao Salvar Protocolo" );  
	        FacesContext.getCurrentInstance().addMessage(null, msg); 
			e.printStackTrace();
		}
    }
	
	public void deleteProtocol(Protocol p) throws Exception{
		FacesContext fc = FacesContext.getCurrentInstance();
		HttpServletRequest request = (HttpServletRequest) fc.getExternalContext().getRequest();
		request.getUserPrincipal();
		dao.excluir(p);
		enviaMensagemInfo(bundle.getString("protocolExcluido"));
	}
	
	public String preparaEdicao(){
		return UrlsBASILI.PAGE_MENU_HOME;
	}
	
	public void removeMetrica( Metric m){
		listaMetricas.remove(m);
	}
	
	public void adicionarPesquisador( ){
		listResearcher.remove(researcher);
		if( researcher != null )
			listResearcher2.add(researcher);
		researcher = new Researcher();
	}
	
//	public void removePesquisador( Researcher research ){
//		listResearcher2.remove(research);
//		listResearcher.add(research);
//	}
	
	public void adicionaMetrica() throws Exception{
		if(protocol.getCodigo() == null && metric != null)
		{
			RelacaoProtocoloMetricaID id = new RelacaoProtocoloMetricaID();
			id.setMetric(++contador);
			metric.setId(id);
			listaMetricas.add(metric);
			metric = new Metric();
		}
	}
	
	public void validaData(){
		if( identification.getEndDate().after(identification.getStartDate()) )
			enviaMensagemInfo(bundle.getString("dataInvalida"));
			
	}
	
	public void adicionaQuestion() {
				question.setMetric(getSelectedMetric());
				listaQuestions.add(question);
				question = new Question();
	}
	
	public void adicionaAH(){
		lAlternativeHypotheses.add(getAlternativeHypotheses());
		alternativeHypotheses = new AlternativeHypotheses();
	}
	
	public void adicionaVD(){
		variable.setType(Type.DEPENDENT);
		listVariable.add(getVariable());
		variable = new Variable();
	}

	public void adicionaVI(){
		variable.setType(Type.INDEPENDENT);
		listVariable.add(getVariable());
		variable = new Variable();
	}
	
	public void adicionaGrupo(){
		listGroups.add(getGroup());
		group = new Troop();
	}
	
	public List<Variable> getListaVI(){
		List<Variable> lista = new ArrayList<Variable>();
		for( Variable var : listVariable )
			if( var.getType() == Type.INDEPENDENT )
				lista.add(var);
		
		return lista;
	}
	
	public List<Variable> getListaVD(){
		List<Variable> lista = new ArrayList<Variable>();
		for( Variable var : listVariable )
			if( var.getType() == Type.DEPENDENT )
				lista.add(var);
		
		return lista;
	}
	
	public void pesquisar() throws Exception{
		setListProtocol(dao.getListProtocolPorParam(title,theme,researcher.getName()));
	}
	
	public List<Protocol> getListProtocol() {
		return listProtocol;
	}

	public void setListProtocol(List<Protocol> listProtocol) {
		this.listProtocol = listProtocol;
	}

	public Protocol getProtocol() {
		return protocol;
	}

	public void setProtocol(Protocol protocol) {
		this.protocol = protocol;
	}

	public Identification getIdentification() {
		return identification;
	}

	public void setIdentification(Identification identification) {
		this.identification = identification;
	}

	public Characterization getCharacterization() {
		return characterization;
	}

	public void setCharacterization(Characterization characterization) {
		this.characterization = characterization;
	}

	public Definition getDefinition() {
		return definition;
	}

	public void setDefinition(Definition definition) {
		this.definition = definition;
	}

	public Planning getPlanning() {
		return planning;
	}

	public void setPlanning(Planning planning) {
		this.planning = planning;
	}

	public CostPlanning getCostPlanning() {
		return costPlanning;
	}

	public void setCostPlanning(CostPlanning costPlanning) {
		this.costPlanning = costPlanning;
	}

	public Introduction getIntroduction() {
		return introduction;
	}

	public void setIntroduction(Introduction introduction) {
		this.introduction = introduction;
	}

	public ResearcherDAO getResearcherDAO() {
		return researcherDAO;
	}

	public void setResearcherDAO(ResearcherDAO researcherDAO) {
		this.researcherDAO = researcherDAO;
	}

	public Researcher getResearcher() {
		return researcher;
	}
	
	public void setResearcher(Researcher researcher) {
		this.researcher = researcher;
	}

	public List<Researcher> getListResearcher() {
		return listResearcher;
	}

	public void setListResearcher(List<Researcher> listResearcher) {
		this.listResearcher = listResearcher;
	}

	public List<Researcher> getListResearcher2() {
		return listResearcher2;
	}

	public void setListResearcher2(ArrayList<Researcher> listResearcher2) {
		this.listResearcher2 = listResearcher2;
	}

	public Study[] getListaTiposEstudo() {
		return Study.values();
	}

	public void setListaTiposEstudo(Study[] listaTiposEstudo) {
		this.listaTiposEstudo = listaTiposEstudo;
	}

	public Context[] getListaContexto() {
		return Context.values();
	}

	public void setListaContexto(Context[] listaContexto) {
		this.listaContexto = listaContexto;
	}

	public ListDataModel<Metric> getListaMetricas() {
		return new ListDataModel<Metric>(listaMetricas);
	}

	public void setListaMetricas(List<Metric> listaMetricas) {
		this.listaMetricas = listaMetricas;
	}

	public Process[] getProcess() {
		return Process.values();
	}

	public void setProcess(Process[] process) {
		this.process = process;
	}

	public Reality[] getReality() {
		return Reality.values();
	}

	public void setReality(Reality[] reality) {
		this.reality = reality;
	}

	public Generality[] getGenerality() {
		return Generality.values();
	}

	public void setGenerality(Generality[] generality) {
		this.generality = generality;
	}

	public void setListResearcher2(List<Researcher> listResearcher2) {
		this.listResearcher2 = listResearcher2;
	}

	public Metric getMetric() {
		return metric;
	}

	public void setMetric(Metric metric) {
		this.metric = metric;
	}

	public Question getQuestion() {
		return question;
	}

	public void setQuestion(Question question) {
		this.question = question;
	}

	public Troop getGroup() {
		return group;
	}

	public void setGroup(Troop group) {
		this.group = group;
	}

	public List<Variable> getListVariable() {
		return listVariable;
	}

	public void setListVariable(List<Variable> listVariable) {
		this.listVariable = listVariable;
	}

	public Variable getVariable() {
		return variable;
	}

	public void setVariable(Variable variable) {
		this.variable = variable;
	}

	public List<RelacaoProtocoloFases> getListRPF() {
		return listRPF;
	}

	public void setListRPF(List<RelacaoProtocoloFases> listRPF) {
		this.listRPF = listRPF;
	}

	public List<AlternativeHypotheses> getlAlternativeHypotheses() {
		return lAlternativeHypotheses;
	}

	public void setlAlternativeHypotheses(
			List<AlternativeHypotheses> lAlternativeHypotheses) {
		this.lAlternativeHypotheses = lAlternativeHypotheses;
	}

	public List<Troop> getListGroups() {
		return listGroups;
	}

	public void setListGroups(List<Troop> listGroups) {
		this.listGroups = listGroups;
	}

	public AlternativeHypotheses getAlternativeHypotheses() {
		return alternativeHypotheses;
	}

	public void setAlternativeHypotheses(AlternativeHypotheses alternativeHypotheses) {
		this.alternativeHypotheses = alternativeHypotheses;
	}

	public List<Question> getListaQuestions() {
		return listaQuestions;
	}

	public void setListaQuestions(List<Question> listaQuestions) {
		this.listaQuestions = listaQuestions;
	}

	public Metric getSelectedMetric() {
		return selectedMetric;
	}

	public void setSelectedMetric(Metric selectedMetric) {
		this.selectedMetric = selectedMetric;
	}

	public String getTitle() {
		return title;
	}

	public void setTitle(String title) {
		this.title = title;
	}

	public String getTheme() {
		return theme;
	}

	public void setTheme(String theme) {
		this.theme = theme;
	}
	
}